package geo.model.utils
{
	import geo.model.wps.ComplexData;
	import geo.model.wps.Data;
	import geo.model.wps.Execute;
	import geo.model.wps.Input;
	import geo.model.wps.ProcessDescription;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	import mx.containers.Canvas;
	import mx.controls.List;
	import mx.core.UIComponent;
	import mx.messaging.AbstractConsumer;
	import mx.skins.halo.TitleBackground;
	import mx.utils.XMLUtil;
	
	public class XMLUtil 
	{
		private static var WPS:Namespace = new Namespace("wps", "http://www.opengis.net/wps/1.0.0");
		private static var OGC:Namespace = new Namespace("ogc", "http://www.opengis.net/ogc");
		private static var OWS:Namespace = new Namespace("ows", "http://www.opengis.net/ows/1.1");
		private static var WFS:Namespace = new Namespace("wfs", "http://www.opengis.net/wfs");
		private static var GML:Namespace = new Namespace("gml", "http://www.opengis.net/gml");
		private static var W3C:Namespace = new Namespace("w3c", "http://www.w3.org/XML/1998/namespace");
		
		public static function toProcessTree(xml:XML):XMLList {
			var nsRegEx:RegExp = new RegExp(" xmlns(?:.*?)?=\".*?\"", "wps");
			
			var resultXML:XML = new XML(String(XML).replace(nsRegEx, "")); 
			return xml.children();
		}
		
		public static function toAC(xml:XML):ArrayCollection {
			var ac:ArrayCollection = new ArrayCollection();
			for each(var p:String in xml..WPS::Process..OWS::Identifier){
				var procArr:Array = p.split(":");
				//var ns:String = p.split(":",1)[0];
				//var process:String = p.split(":",1)[2];
				var obj:Object = {Process:procArr[1],NS:procArr[0]};
				ac.addItem(obj);
			}
			return ac;
		}
		
		public static function toProcessDescription(xml:XML):ProcessDescription {
			var processDescription:ProcessDescription = new ProcessDescription();
			processDescription.inputFormats = new Array();
			processDescription.outputFormats = new Array();
			processDescription.dataInputs = new ArrayCollection();
			
			// Process Description identifier 
			processDescription.identifier = xml..OWS::Identifier[0];
			
			// Process Description title description
			processDescription.title = xml..OWS::Title[0];
			
			// Process Description title description
			processDescription.abstract = xml..OWS::Abstract[0];
			
			// Process Description DataInputs
			for each(var dataInput:XML in xml..Input) {
				var input:Input = new Input();
				input.identifier = dataInput..OWS::Identifier[0];
				input.title = dataInput..OWS::Title[0];
				input.abstract = dataInput..OWS::Abstract[0];
				
				// DataInputs ComplexData
				for each(var data:XML in dataInput..ComplexData) {
					// Declare Data and Complex Data objects
					var dataObject:Data = new Data();
					var complexDataObj:ComplexData = new ComplexData();
					
					// Declare default and supported format array lists
					complexDataObj.defaultFormatList = new ArrayList();
					complexDataObj.supportedFormatList = new ArrayList();
					
					// Add Default and Supported formats to ComplexData object
					complexDataObj.defaultFormatList.addItem(data..Default);
					complexDataObj.supportedFormatList.addItem(data..Supported);
					
					// Add ComplexData object to the Data object wrapper
					dataObject.complexData = complexDataObj;
					
					// Add Data object to Input object
					input.data = dataObject;
					
					// Add Input object to the process desciption inputs collection
					processDescription.dataInputs.addItem(input);
				}
			}
			
			// Process Description supported inputs
			for each(var s:String in xml..DataInputs..Supported..MimeType) {
				processDescription.inputFormats.push(s);
			}
			
			// Process Description supported output types
			for each(var str:String in xml..ProcessOutputs..Supported..MimeType) {
				processDescription.outputFormats.push(str);
			}
			
			return processDescription;
		}
		
		// ***For debug purposes only****
		public static function printProcessDescription(processDescription:ProcessDescription):void {
			trace("Process Description Identifier: " + processDescription.identifier);
			trace("Process Description Title: " + processDescription.title);
			trace("Process Description Abstract: " + processDescription.abstract);
			
			trace("Process Description outputFormats: ");
			for each(var s:String in processDescription.outputFormats) {
				trace(s);
			}
			
			trace("Process Description inputFormats: ");
			for each(var str:String in processDescription.inputFormats) {
				trace(str);
			}
			
			for each (var dataInput:Input in processDescription.dataInputs){
				trace("DataInput Identifier: " + dataInput.identifier);
				trace("DataInput Description Title: " + dataInput.title);
				trace("DataInput Description Abstract: " + dataInput.abstract);
				trace("DataInput ComplexData DefaultFormatList: " + dataInput.data.complexData.defaultFormatList);
				trace("DataInput ComplexData SupportedFormatList: " + dataInput.data.complexData.supportedFormatList);
			}
		}
		
		public static function buildExecuteXML(wf:Canvas):XML {
			var subprocessList:ArrayCollection = new ArrayCollection();
			var processList:ArrayCollection = new ArrayCollection();
			var executeXML:XML = new XML();
			for (var i:int = 0; i < wf.numElements; i++){
				var obj:Object = wf.getElementAt(i);
				if (!(obj is Execute)) {
					var u:UIComponent  = obj as UIComponent ;
					var connector:Connector = u.getChildAt(0) as Connector;
					if (connector.getParent() != null && !subprocessList.contains(connector.getParent() as Execute)){
						var subprocess:Execute = connector.getParent() as Execute;
						var spXML:XML = toExecuteXML(subprocess);
					}
					if (connector.getChild() != null && !processList.contains(connector.getChild() as Execute)) {
						var process:Execute = connector.getChild() as Execute;
						var pXML:XML = toExecuteXML(process);
					}
					if (spXML.length() > 0) {
						//different reference for child1
						trace("pXML:" + pXML);
						pXML..WPS::DataInputs..WPS::Input.appendChild(<wps:Reference xmlns:wps={WPS}/>);
						pXML..WPS::Reference.appendChild(spXML);
						trace("pXML:" + pXML);						

					}
					executeXML = pXML;
				}
			}
			return executeXML;
		}
		
		public static function toExecuteXML(execute:Execute):XML {
			var executeXML:XML = <wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps={WPS} xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"/>;
			executeXML.appendChild(<ows:Identifier xmlns:ows={OWS}>{execute.identifier}</ows:Identifier>);
			executeXML.appendChild(<wps:DataInputs xmlns:wps={WPS}/>);
			executeXML..WPS::DataInputs.appendChild(<wps:Input xmlns:wps={WPS}/>);
			executeXML..WPS::DataInputs..WPS::Input.appendChild(<ows:Identifier xmlns:ows={OWS}>{"input param"}</ows:Identifier>);
			return executeXML;
		}
	}
}